<?php
class ZfApplication {
	/**
	 * The environment state of your current application
	 *
	 * @var string
	 */
	protected $_environment;

	/**
	 * Sets the environment to load from configuration file
	 *
	 * @param string $environment - The environment to set
	 * @return void
	 */
	public function setEnvironment($environment) {
		$this->_environment = $environment;
	}

	/**
	 * Returns the environment which is currently set
	 *
	 * @return string
	 */
	public function getEnvironment() {
		return $this->_environment;
	}

	/**
	 * Convenience method to bootstrap the application
	 *
	 * @return mixed
	 */
	public function bootstrap() {
		if (!$this->_environment) {
			throw new Exception('Please set the environment using ::setEnvironment');
		}
		
		$frontController = $this->initialize();

		//include the define for apps
		require_once ('app/etc/define.php');

		//initial the acl configure info
		require_once ('app/plugins/AclPlugin.php');
		$frontController->registerPlugin(new AclPlugin());
		
		/*initial the Zend_Auth storage*/
		require_once 'app/plugins/AuthStorage.php';
		Zend_Auth::getInstance()->setStorage(new TT_Auth_Storage());

		$this->setupRoutes($frontController);
		$response = $this->dispatch($frontController);
		$this->render($response);
	}

	/**
	 * Initialization stage, loads configration files, sets up includes paths
	 * and instantiazed the frontController
	 *
	 * @return Zend_Controller_Front
	 */
	public function initialize() {
		// Set the include path
		set_include_path(dirname(__FILE__) . '/app/model' . PATH_SEPARATOR.dirname(__FILE__) . '/app/plugins' . PATH_SEPARATOR . get_include_path());

		/*use the following components. require will throw a fatal error when the file not exists*/
		require_once 'Zend/Auth.php';
		require_once 'Zend/Cache.php';
		require_once 'Zend/Config/Ini.php';
		require_once 'Zend/Controller/Front.php';
		require_once 'Zend/Controller/Router/Rewrite.php';
		require_once 'Zend/Controller/Action/HelperBroker.php';
		require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';
		require_once 'Zend/Loader.php';
		require_once 'Zend/Registry.php';
		require_once 'Zend/Session.php';
		require_once 'Zend/View.php';
		
		require_once 'Zend/Db.php';
		require_once 'Zend/Db/Table.php';

		//initial the utils class
		require_once ('app/lib/Utils.php');

		//initial the menu tool
		require_once ('app/model/Menu.php');

		/* Start the Session */
		Zend_Session :: start();

		/*
		 * Load the given stage from our configuration file,
		 * and store it into the registry for later usage.
		 */
		$config = new Zend_Config_Ini(dirname(__FILE__) . '/app/etc/config.ini', $this->getEnvironment());
		Zend_Registry :: set('config', $config);
		
		/* @see config.ini , we can define config as below:
				database.adapter         = pdo_mysql
				database.parmas.host     = 127.0.0.1
				database.parmas.username = test
				database.parmas.password = 123456
				database.parmas.dbname   = test
			now we can use method toArray() to get an array:
        */
		$db_params_default = $config->database->params->toArray();
		/*
		$db_params_default = array (
			'host' => $config->database->host,
			'username' => $config->database->username,
			'password' => $config->database->password,
			'dbname' => $config->database->name
		);*/		
		Zend_Registry :: set('db_params_default', $db_params_default);
		
		/*Initial the Zend_Db_Table for models*/
		//$db = Zend_Db::factory('PDO_MYSQL', $db_params_default);

		//we can use method toArray()
		//$db = Zend_Db::factory($config->database->adapter, $config->database->config->toArray());

		$db = Zend_Db::factory($config->database);    //Zend_Db can accept Zend_Config object yet

		//$db->query("set names utf-8"); // deal with chinese
		Zend_Db_Table::setDefaultAdapter($db);
		Zend_Registry::set('db_adapter', $db);

		/*Initial the cache*/
		$frontendOptions = $config->cache->frontend->toArray();
        $backendOptions = $config->cache->backend->toArray();
		
		$cache = Zend_Cache::factory('Core', $config->cache->type, $frontendOptions, $backendOptions);
		Zend_Registry::set('cache', $cache);

		/*
		 * Create an instance of the frontcontroller, and point it to our
		 * controller directory
		 */
        $frontController = Zend_Controller_Front::getInstance()
                         ->throwExceptions((bool)$config->mvc->exceptions)
                         ->setControllerDirectory(dirname(__FILE__) . '/app/controllers');

		return $frontController;
	}

	/**
	 * Sets up the custom routes
	 *
	 * @param  object Zend_Controller_Front $frontController - The frontcontroller
	 * @return object Zend_Controller_Router_Rewrite
	 */
	public function setupRoutes(Zend_Controller_Front $frontController) {
		// Retrieve the router from the frontcontroller
		$router = $frontController->getRouter();

		/*
		 * You can add routes here like so:
		 * $router->addRoute(
		 *    'home',
		 *    new Zend_Controller_Router_Route('home', array(
		 *        'controller' => 'index',
		 *        'action'     => 'index'
		 *    ))
		 * );
		 */

		return $router;
	}

	/**
	 * Dispatches the request
	 *
	 * @param  object Zend_Controller_Front $frontController - The frontcontroller
	 * @return object Zend_Controller_Response_Abstract
	 */
	public function dispatch(Zend_Controller_Front $frontController) {
		// Return the response
		$frontController->returnResponse(true);
		return $frontController->dispatch();
	}

	/**
	 * Renders the response
	 *
	 * @param  object Zend_Controller_Response_Abstract $response - The response object
	 * @return void
	 */
	public function render(Zend_Controller_Response_Abstract $response) {
		$response->sendHeaders();
		$response->outputBody();
	}
}
?>